package exttable.testselector;

import dbutils.DbUtils;
import dbutils.StringQueries;
import exttable.timetable.TimeTableSaver;
import exttable.view.ViewAnalysis;
import utils.Localisation;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.*;

import java.sql.Date;

/**
 * Created by IntelliJ IDEA.
 * User: Admin
 * Date: Jan 14, 2010
 * Time: 1:20:10 AM
 * To change this template use File | Settings | File Templates.
 */
public class TimeTableGenerator {

    private int groupId;
    private String analysisType;
    private int schemaVisitId;
    private Integer visitCount;
    private int probationerId;
    private Vector<String> visitNames = new Vector<String>();
    private List<ViewAnalysis> mapAnalysis = new ArrayList<ViewAnalysis>();

    private Date probationerVisitZero;
    private Map<Integer, Long> mapVisitsTime = new HashMap<Integer, Long>();

    public TimeTableGenerator() {
    }

    public int getGroupId() {
        return groupId;
    }

    public String getAnalysisType() {
        return analysisType;
    }

    public int getSchemaVisitId() {
        return schemaVisitId;
    }

    public int getVisitCount() {
        return visitCount;
    }

    public int getProbationerId() {
        return probationerId;
    }

    public Vector<String> getVisitNames() {
        return visitNames;
    }

    public Date getProbationerVisitZero() {
        return probationerVisitZero;
    }

    public void setProbationerVisitZero(Date probationerVisitZero) {
        this.probationerVisitZero = probationerVisitZero;
    }

    public TimeTableGenerator(int groupId, String analysisType, int schemaVisitId, int probationerId, Date probationerVisitZero) throws Exception {
        this.groupId = groupId;
        this.analysisType = analysisType;
        this.schemaVisitId = schemaVisitId;
        this.probationerId = probationerId;
        this.probationerVisitZero = probationerVisitZero;
        initVisitCount();
        initAnalysisNames();
        initVisitNames();

    }

    private void initVisitCount() throws Exception {
        try {
            Connection c = DbUtils.getDBConnectionGeneral();
            PreparedStatement ps = c.prepareStatement(StringQueries.VISIT_COUNT);
            ps.setInt(1, schemaVisitId);
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                visitCount = rs.getInt(1);
            }
            ps.close();
            c.close();
        } catch (Exception e) {
            throw new Exception("no connection");
        }
    }

    private void initAnalysisNames() throws Exception {
        try {
            Connection c = DbUtils.getDBConnectionGeneral();
            PreparedStatement ps = c.prepareStatement(StringQueries.ANALYSIS_NAMES);
            ps.setInt(1, schemaVisitId);
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                ViewAnalysis av = new ViewAnalysis.Build()
                        .analysName(rs.getString(1))
                        .analysId(rs.getInt(2))
                        .nameRu(rs.getString(3))
                        .nameEn(rs.getString(4))
                        .nameKz(rs.getString(5)).build();
                av.setAnalysisVersionKey(rs.getString("tpu.analysis_version_key"));
                mapAnalysis.add(av);
            }
            c.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void initVisitNames() throws Exception {
        try {
            visitNames.add(Localisation.getMessage("form.analysname"));
            Connection conn = DbUtils.getDBConnectionGeneral();
            PreparedStatement ps = conn.prepareStatement("SELECT * from schema_visit_time where schema_visits_id " +
                    "IN(" +
                    "SELECT schema_visits_id from groups_schema_visits " +
                    "WHERE groups_schema_visits_id=?" +
                    ")");
            ps.setString(1, String.valueOf(schemaVisitId));
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                mapVisitsTime.put(rs.getInt("visit_id"), (Long.valueOf(rs.getString("time_mls"))*1000));
                if (Integer.parseInt(rs.getString(3)) == 0 && rs.getString(2).equals("1")) {
                    visitNames.add(Localisation.getMessage("timetable.beforeTakingDrug"));
                } else if (Integer.parseInt(rs.getString(3)) == 0 && rs.getString(2).equals("2")) {
                    visitNames.add(Localisation.getMessage("timetable.takingDrug"));
                } else if (Integer.parseInt(rs.getString(3)) > 0 &&
                        Integer.parseInt(rs.getString(3)) < TimeTableSaver.DAYS_TO_SECONDS) {
                    visitNames.add(Integer.parseInt(rs.getString(3)) / TimeTableSaver.HOURS_TO_SECONDS + " (" +
                            Localisation.getMessage("timetable.hour") + ")");

                } else {
                    visitNames.add(Localisation.getMessage("timetable.days") + "  " +
                            (Integer.parseInt(rs.getString(3))) / TimeTableSaver.DAYS_TO_SECONDS);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public Vector<Vector> getTimeTable() throws Exception {
        Connection c = DbUtils.getDBConnectionGeneral();
        Vector<Vector> toReturn = new Vector<Vector>();
        for (ViewAnalysis resA : mapAnalysis) {
            Vector<Object> v1 = new Vector<Object>();
            v1.add(resA);
            for (int resV = 1; resV <= visitCount; resV++) {
                PreparedStatement ps = c.prepareStatement(StringQueries.TIME_TABLE);
                ps.setInt(1, schemaVisitId);
                ps.setString(2, resA.getAnalysisVersionKey());
                ps.setInt(3, resV);
                ResultSet rs = ps.executeQuery();
                while (rs.next()) {
                    if (rs.getInt(1) == 1) {
                        v1.add(isResultPresent(resV, probationerId, schemaVisitId, resA.getAnalysisName(), c));
                    }
                    if (rs.getInt(1) == 0) {
                        v1.add(Localisation.getMessage("timetable.noreq"));
                    }
                }
            }
            toReturn.add(v1);
        }
        c.close();
        return toReturn;
    }

    private String isResultPresent(int visitId, int probId, int groupSchema, String analysis, Connection con) throws Exception {
        String toReturn="";

        String query = String.format(StringQueries.RESULT_PRESENT, analysis);
        PreparedStatement ps = con.prepareStatement(query);
        ps.setInt(1, probId);
        ps.setInt(2, visitId);
        ps.setInt(3, groupSchema);
        ResultSet rs = ps.executeQuery();
            if (rs.next()) {
                toReturn = Localisation.getMessage("timetable.result");
            } else {
                if(isFutureDay(probationerVisitZero, mapVisitsTime.get(visitId))){
                  toReturn = Localisation.getMessage("timetable.waiting");
                }else {
                  toReturn = Localisation.getMessage("timetable.fill");
                }

            }
        return toReturn;
    }

    public static boolean isFutureDay(java.sql.Date probationerVisitZero, Long visitTime) {
        Calendar calendarDateVisitZero = Calendar.getInstance();
        calendarDateVisitZero.setTime(probationerVisitZero);
        Long longDateVisitZero=calendarDateVisitZero.getTimeInMillis();
        Calendar calendarCurrentDate=Calendar.getInstance();
        if (longDateVisitZero+visitTime>calendarCurrentDate.getTimeInMillis()){
            return true;
        }
        return false;
    }
}
